//
//  ChromaticityHistogramView.m
//  ToneMapper
//
//  Created by Andrey on 26/04/2009.
//  Copyright 2009 Karma Software. All rights reserved.
//

#import "ChromaticityHistogramView.h"
#import "KSegmentationMap.h"
#import "KHistogram.h"
#import "K2DHistrogram.h"

@implementation ChromaticityHistogramView

@synthesize highlightedCell;

- (id)initWithFrame: (NSRect)frame 
{
    self = [super initWithFrame:frame];
	
    if (self) 
	{
        
    }
    return self;
}

- (BOOL) isFlipped
{
	return FALSE;
}

- (void)drawRect: (NSRect)rect 
{
    if (controller.currentImage != nil)
	{
		if (controller.displayedChromaticityHistogramChannel == HueChromaticityChannel)
		{
			KHistogram* histogram = controller.currentImage.histogram;
			KChannelHistogram hueHistogram = 
			histogram.channelHistograms[HueImageChannel];
			
			NSRect frameRect = rect;
			
			CGFloat histogramRadius = 0.7 * (frameRect.size.width / 2);
			CGFloat scalingFactor = 
			(frameRect.size.width / 2 - histogramRadius) / hueHistogram.maxPixelsPerInterval;
			
			NSPoint frameCenter =  
			NSMakePoint(frameRect.origin.x + frameRect.size.width / 2, 
						frameRect.origin.y + frameRect.size.height / 2);
			
			NSBezierPath* path = [NSBezierPath bezierPath];
			[path setLineWidth: 2.0];
			
			CGFloat angleStep = 2 * pi / histogram.intervalCount;
			CGFloat gravityCenterX = 0.0;
			CGFloat gravityCenterY = 0.0;
			NSUInteger filledIntervalCount = 0;
			for (int i = 0; i < histogram.intervalCount; i++)
			{
				CGFloat angle = i * angleStep;
				NSUInteger value = hueHistogram.data[i];
				
				NSPoint pointOnCircle = NSMakePoint(frameCenter.x + histogramRadius * cos(angle), 
													frameCenter.y + histogramRadius * sin(angle));
				
				[path moveToPoint: pointOnCircle];
				
				NSPoint histogramPlotPoint =
				NSMakePoint(frameCenter.x + 
							(histogramRadius + value * scalingFactor + 1) * cos(angle), 
							frameCenter.y + 
							(histogramRadius + value * scalingFactor + 1) * sin(angle));
				
				NSColor* lineColor = [NSColor colorWithCalibratedHue:angle / (2 * pi) 
														  saturation:1.0
														  brightness:1.0
															   alpha:1.0];

				[lineColor set];
				[path lineToPoint: histogramPlotPoint];
				[path stroke];
				[path removeAllPoints];
				
				gravityCenterX += pointOnCircle.x * (value > 0 ? 1 : 0);
				gravityCenterY += pointOnCircle.y * (value > 0 ? 1 : 0);
				filledIntervalCount += (value > 0 ? 1 : 0);
			}
			
			gravityCenterX /= filledIntervalCount;
			gravityCenterY /= filledIntervalCount;
			NSRect boundingRectForCircle = 
			NSMakeRect(gravityCenterX - 3, gravityCenterY - 3, 6, 6);
			
			[path appendBezierPathWithOvalInRect:boundingRectForCircle];
			[[NSColor lightGrayColor] set];
			[path stroke];
			[path removeAllPoints];
			
			boundingRectForCircle = NSMakeRect(frameCenter.x - 1, frameCenter.y - 1, 2, 2);
			[path appendBezierPathWithOvalInRect:boundingRectForCircle];
			[[NSColor blackColor] set];
			[path stroke];
		}
		else if (controller.displayedChromaticityHistogramChannel == ABChromaticityChannel)
		{
			K2DHistrogram* cieABHistogram = controller.currentImage.cieABHistogram;
			NSUInteger histogramWidth = 
			(NSUInteger)sqrt(cieABHistogram.intervalCount);
			NSBitmapImageRep* histogramImage = 
			[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL 
													pixelsWide:histogramWidth 
													pixelsHigh:histogramWidth
												 bitsPerSample:8
											   samplesPerPixel:3
													  hasAlpha:NO
													  isPlanar:NO
												colorSpaceName:NSCalibratedRGBColorSpace
												   bytesPerRow:0
												  bitsPerPixel:0];
			// Draw axis
			for (int i = 0; i < histogramWidth; i++)
			{
				CGFloat colorFraction = (CGFloat)i / histogramWidth; 
				
				NSColor* aAxisColor = 
				[[NSColor greenColor] blendedColorWithFraction:colorFraction 
													   ofColor:[NSColor magentaColor]];
				
				NSColor* bAxisColor =
				[[NSColor blueColor] blendedColorWithFraction:colorFraction 
													   ofColor:[NSColor yellowColor]];
				
				[histogramImage setColor:aAxisColor atX:i y:histogramWidth - 1];
				[histogramImage setColor:bAxisColor 
									 atX:0
									   y:histogramWidth - i];
			}
			
			// Draw histogram
			for (int i = 0; i < histogramWidth; i++)
			{
				for (int j = 0; j < histogramWidth; j++)
				{
					NSUInteger index = j * histogramWidth + i;
					NSUInteger value = cieABHistogram.channelHistograms[0].data[index];
					CGFloat intensity = 
					(CGFloat)value / 
					cieABHistogram.channelHistograms[0].maxPixelsPerInterval;
					
					if (intensity > 0.0)
					{
						//CGFloat aColorFraction = (CGFloat)i / 
						
						NSColor* color = 
						[NSColor colorWithCalibratedRed:intensity 
												  green:intensity 
												   blue:intensity 
												  alpha:1.0];
						
						[histogramImage setColor:color atX:i y:(histogramWidth - j)];
					}
				}
			}
			
			// Draw centroids
			if (controller.useChromaticityForSegmentation == YES && 
				controller.chromaticitySegmentationMap != nil)
			{
				NSPointArray centroids = controller.chromaticitySegmentationMap.centroidPoints;
				NSUInteger centroidCount = controller.chromaticitySegmentationMap.segmentCount;
				
				for (int i = 0; i < centroidCount; i++)
				{
					NSPoint centroidImage;
					
					centroidImage.x = centroids[i].x * histogramWidth;
					centroidImage.y = (1 - centroids[i].y) * histogramWidth;
					
					[histogramImage setColor:[NSColor greenColor] 
										 atX:centroidImage.x 
										   y:centroidImage.y];
				}
			}
			
			// Draw highlighted cell - UGLY!
			[histogramImage setColor:[NSColor redColor] 
								 atX:highlightedCell.x 
								   y:highlightedCell.y];
			[histogramImage setColor:[NSColor redColor] 
								 atX:highlightedCell.x + 1 
								   y:highlightedCell.y];
			[histogramImage setColor:[NSColor redColor] 
								 atX:highlightedCell.x 
								   y:highlightedCell.y + 1];
			[histogramImage setColor:[NSColor redColor] 
								 atX:highlightedCell.x - 1 
								   y:highlightedCell.y];
			[histogramImage setColor:[NSColor redColor] 
								 atX:highlightedCell.x 
								   y:highlightedCell.y - 1];
			
			[histogramImage drawInRect:rect];
		}
	}
}

@end
